#include <gtest/gtest.h>
#include <iostream>
#include "Mystring.hpp"
using namespace cr;

// TestCase 事件(即: 全局事件+TestSuite 事件)

class StringTest : public testing::Test
{
public:
    static void SetUpTestCase() // 全局单元测试
    {
        // 处理全局的测试数据对象
        std::cout << "全局单元测试初始化" << std::endl;
    }

    virtual void SetUp() override // 独立单元测试
    {
        // 处理每个单元测试所需的独立数据对象（成员对象）
        std::cout << "当前单元测试初始化" << std::endl;
        s = "abcdefghij";
    }

    virtual void TearDown() override
    {
        std::cout << "当前单元测试环境释放" << std::endl;
    }

    static void TearDownTestCase()
    {
        std::cout << "全局单元测试释放" << std::endl;
    }

public:
    MyString s;
};

TEST_F(StringTest, construct) // 每个单元测试中的对象都独立
{
    MyString tmp("abcdefg");
    std::cout << tmp << std::endl;
    ASSERT_EQ(tmp.size(), 7);
    ASSERT_EQ(tmp.capacity(), 8);

    MyString tmp1 = tmp;
    std::cout << tmp1 << std::endl;
    ASSERT_EQ(tmp1.size(), 7);
    ASSERT_EQ(tmp1.capacity(), 8);

    tmp1 = "abcdefgh";
    std::cout << tmp1 << std::endl;
    ASSERT_EQ(tmp1.size(), 8);
    ASSERT_EQ(tmp1.capacity(), 16);

    ASSERT_EQ(tmp.empty(), false);
}
TEST_F(StringTest, reverse)
{
    std::cout << s << std::endl;

    ASSERT_EQ(s.size(), 10);
    ASSERT_EQ(s.capacity(), 16);

    s.reverse(5);
    ASSERT_EQ(s.size(), 10);
    ASSERT_EQ(s.capacity(), 16);

    s.reverse(20);
    ASSERT_EQ(s.size(), 10);
    ASSERT_EQ(s.capacity(), 32);
}

TEST_F(StringTest, resize)
{
    s.resize(5);
    ASSERT_EQ(s.size(), 5);
    std::cout << s << std::endl;

    s.resize(20, 'a');
    ASSERT_EQ(s.size(), 20);
    std::cout << s << std::endl;
}

TEST_F(StringTest, push)
{
    s += 'a';
    std::cout << s << std::endl;
    s += "abc";
    std::cout << s << std::endl;
}

TEST_F(StringTest, operator)
{
    MyString s1="abcd",s2="abcd";
    ASSERT_EQ(s1>=s2,true);
}

TEST_F(StringTest, iterator)
{
    for (auto &c : s)
    {
        std::cout << c << ' ';
    }
    std::cout << std::endl;

    MyString tmp = "opqrst";
    MyString::iterator it = tmp.begin();
    while (it.operator!=(tmp.end()))
    {
        (*it)++;
        it++;
    }
    std::cout << tmp << std::endl;

    MyString::reverse_iterator rit = tmp.rbegin();
    while (rit != tmp.rend())
    {
        std::cout << *rit << ' ';
        rit++;
    }
    std::cout << std::endl;
}

TEST_F(StringTest, const_iterator)
{
    const MyString s = "abcdr";
    MyString::const_iterator it = s.begin();
    while (it != s.end())
    {
        // (*it)++;
        it++;
    }
    std::cout << s << std::endl;
}

TEST_F(StringTest, in)
{
    MyString s;
    std::cin >> s;
    std::cout << s << std::endl;
}

TEST_F(StringTest, find)
{
    MyString str("There are two needles in this haystack with needles.");
    MyString str2("needle");

    std::size_t found = str.find(str2);
    if (found != std::string::npos)
        std::cout << "first 'needle' found at: " << found << '\n';

    found = str.find("needles", found + 1);
    if (found != std::string::npos)
        std::cout << "second 'needle' found at: " << found << '\n';

    found = str.find("haystack");
    if (found != std::string::npos)
        std::cout << "'haystack' also found at: " << found << '\n';

    found = str.find('.');
    if (found != std::string::npos)
        std::cout << "Period found at: " << found << '\n';
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);

    return RUN_ALL_TESTS();
}